package ks.framework.common;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;


/**
 * Helper class whose only purpose is to simplify the process of securing the appropriate
 * ks.xsd file to use. If there is no Internet connection, then at least a local copy
 * (which may be marginally out of date) is to be used. 
 * 
 * @author George Heineman 
 */
public class Configure {
	
	/** Default file. */
	public static final String DEFAULT_KS_XSD = "ks.xsd";
	
	/** Default URL. */
	public static final String DEFAULT_KS_URL = "http://www.wpi.edu/~heineman/xml/ks.xsd";
	
	/** Default XSD Name. */
	public static final String XSD_NAME = "ks.xsd";
	
	/**
	 * Properly configure the XML schema definition file we are to use.
	 * 
	 * @return  true if successful in either attempt to retrieve ks.xsd via the Internet
	 * or using local copy
	 */
	public static boolean configure() {
		if (configureURL(DEFAULT_KS_URL)) {
			return true;
		}
		
		return configureLocal(DEFAULT_KS_XSD);
	}
	
	// record last known FAILURE and cache it to save headaches later during testing. HACK
	static String lastFailedURL = "";
	
	/**
	 * Helper function to load up schema definition file from given HTTP
	 * Address.
	 */
	static boolean configureURL(String httpAddress) {
		// Determine the XML schema we are going to use. First try to see if we
		// have internet access to get most recent one. Otherwise, use our local
		// copy and cross-fingers to hope it works.
		URL url = null;
		try {
			url = new URL(httpAddress);
		} catch (MalformedURLException e) {
			// ignore
		}
		
		if (url == null) { 
			return false;
		}
		
		if (lastFailedURL.equals(httpAddress)) {
			return configureLocal(DEFAULT_KS_XSD);
		}
		
		// Try to access the ks.xsd via the Internet. If it works, configure and 
		// we are done.
		try {
			URLConnection con = url.openConnection();
			InputStream is = con.getInputStream();
			if (is != null) {
				Message.configure(XSD_NAME, url);
				return true;
			}
		} catch (IllegalStateException e) {
			System.err.println(e.getMessage());
		} catch (IOException e) {
			System.err.println(e.getMessage());
		}
		
		// cache this value so we can avoid looking for it again.
		lastFailedURL = httpAddress;
		
		return configureLocal(DEFAULT_KS_XSD);
	}
	
	/**
	 * Helper function to load up schema definition file locally
	 * when internet connection is disabled.
	 * 
	 */
	static boolean configureLocal(String file) {
		// if we get here, try to access local copy
		File f = new File (file);
		URI uri = f.toURI();
		URL url;
		try {
			url = uri.toURL();
			try {
				URLConnection con = url.openConnection();
				InputStream is = con.getInputStream();
				if (is != null) {
					System.err.println("Using local copy of " + file + ". May be out of date...");
					Message.configure(XSD_NAME, url);
					return true;
				}
			} catch (IllegalStateException e) {
				// pass through
			} catch (IOException e) {
				// pass through
			}
		} catch (MalformedURLException e) {
			// pass through
		}
		
		System.err.println("Unable to access local ks.xsd file");
		return false;
	}
}
